using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;
using Constants=PHSRAG.Insight21.InsightUtilities.Constants;

namespace PHSRAG.Insight21.Admin
{
    /// <summary>
    /// The page facilitates the search and display of Admin HR departments.
    /// </summary>
    public partial class AdminSearchHRDepartments : BasePage
    {
        #region Constants

        private const int HRDepartmentsTableIndex = 0;
        private const string HRDepartmentsTableName = "HRDepartments";
        private const int UnmanagedHRDeptMgmtStatusTypeID = 3;
        private const int UnmanagedHRDeptMgmtStatusTypeIndex = 1;

        #endregion

        #region Private Variables

        private ICachePolicy cachePolicy;
        private HRDepartments hrDepartments;
        private Hashtable hrDeptPageInfo;

        #endregion

        #region Private Properties

        private Hashtable HRDeptPageInfo
        {
            get
            {
                if (hrDeptPageInfo == null)
                {
                    hrDeptPageInfo = (Hashtable) Session[Keys.SearchHRDeptsPageKey];
                }
                return hrDeptPageInfo ?? (hrDeptPageInfo = new Hashtable());
            }
            set { Session[Keys.SearchHRDeptsPageKey] = value; }
        }

        private bool SortAscending
        {
            get
            {
                object o = HRDeptPageInfo[Keys.SortDirectionKey];
                return (o == null) ? true : (bool) o;
            }
            set
            {
                HRDeptPageInfo[Keys.SortDirectionKey] = value;
                HRDeptPageInfo = hrDeptPageInfo;
            }
        }

        private HRDepartments HRDepartments
        {
            get
            {
                hrDepartments = cachePolicy.GetCachedObject(HRDepartments.CacheKey) as HRDepartments;
                if (hrDepartments == null)
                {
                    hrDepartments = new HRDepartments(cachePolicy);
                    hrDepartments.Load(DataAccess.GetConnectionString(),
                        hrDepartmentCode.Text.Trim() == string.Empty ? DBNull.Value : (object) hrDepartmentCode.Text.Trim(),
                        userName.Text.Trim() == string.Empty ? DBNull.Value : (object) userName.Text.Trim(),
                        lastName.Text.Trim() == string.Empty ? DBNull.Value : (object) lastName.Text.Trim(),
                        firstName.Text.Trim() == string.Empty ? DBNull.Value : (object) firstName.Text.Trim());
                    hrDepartments.Cache();
                }
                return hrDepartments;
            }
        }

        private string HRDepartmentCode
        {
            get
            {
                object o = HRDeptPageInfo[Keys.HRDepartmentCodeKey];
                return o == null ? string.Empty : (string) o;
            }
            set
            {
                HRDeptPageInfo[Keys.HRDepartmentCodeKey] = value;
                HRDeptPageInfo = hrDeptPageInfo;
            }
        }

        private string Username
        {
            get
            {
                object o = HRDeptPageInfo[Keys.UsernameKey];
                return o == null ? string.Empty : (string) o;
            }
            set
            {
                HRDeptPageInfo[Keys.UsernameKey] = value;
                HRDeptPageInfo = hrDeptPageInfo;
            }
        }

        private string FirstName
        {
            get
            {
                object o = HRDeptPageInfo[Keys.FirstNameKey];
                return o == null ? string.Empty : (string) o;
            }
            set
            {
                HRDeptPageInfo[Keys.FirstNameKey] = value;
                HRDeptPageInfo = hrDeptPageInfo;
            }
        }

        private string LastName
        {
            get
            {
                object o = HRDeptPageInfo[Keys.LastNameKey];
                return o == null ? string.Empty : (string) o;
            }
            set
            {
                HRDeptPageInfo[Keys.LastNameKey] = value;
                HRDeptPageInfo = hrDeptPageInfo;
            }
        }

        #endregion

        #region Private Methods

        private void LoadDataGrid()
        {
            dataGrid.DataSource = HRDepartments.GetDataContainer();
            dataGrid.DataBind();
            ManageControlVisibility();
        }

        private void UpdateSearchCriteria()
        {
            if (hrDepartmentCode.Text != string.Empty)
            {
                HRDepartmentCode = hrDepartmentCode.Text;
            }
            if (userName.Text != string.Empty)
            {
                Username = userName.Text;
            }
            if (lastName.Text != string.Empty)
            {
                LastName = lastName.Text;
            }
            if (firstName.Text != string.Empty)
            {
                FirstName = firstName.Text;
            }
        }

        private void ManageControlVisibility()
        {
            save.Visible = dataGrid.Visible = dataGrid.Items.Count != 0;
            annunciator.Visible = !save.Visible;
            if (annunciator.Visible)
            {
                annunciator.Message = "No HR Departments returned based on your criteria.";
            }
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Loads the datagrid with data only if there is HR department data stored in session.
        /// Also adds this page to the breadcrumb.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            breadCrumb.Add("Search HR Departments",
                "AdminSearchHRDepartments.aspx",
                Settings.GetKeyValue("BreadCrumb.SummaryPageLevel", 1));

            if (!IsPostBack && HRDeptPageInfo.Values.Count > 0)
            {
                LoadDataGrid();
            }
            else
            {
                ManageControlVisibility();
            }
        }

        /// <summary>
        /// Search button event handler. It only loads data is the page passed validations.
        /// It also uncaches the HRdepartments and updates search criteria in session.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnSearch(object sender, ImageClickEventArgs e)
        {
            if (IsValid)
            {
                //UpdateSearchCriteria();
                // this is a hack, but otherwise the HRDepartments object was getting loaded twice:
                // once right before being uncached and then again to load the datagrid
                cachePolicy.UnCache(HRDepartments.CacheKey);
                LoadDataGrid();
            }
        }

        /// <summary>
        /// Adds the sort symbol to all sortable columns.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnItemCreated(object sender, DataGridItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Header)
            {
                Label sortSymbol = new Label();
                sortSymbol.Text = SortAscending ? Constants.SortAscendingText : Constants.SortDescendingText;
                sortSymbol.Font.Name = Constants.SortSymbolFontName;
                e.Item.Cells[1].Controls.Add(sortSymbol);
            }
        }

        /// <summary>
        /// Sets the right value of management status.
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnItemDataBound(object sender, DataGridItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                RadioButtonList managementStatusList = (RadioButtonList) e.Item.FindControl("managementStatusList");
                string hrDepartmentManagementTypeID = Convert.ToString(((DataRowView) e.Item.DataItem)["HRDepartmentManagementTypeID"]);
                if (hrDepartmentManagementTypeID == "1")
                {
                    hrDepartmentManagementTypeID = "2";
                }
                ListItem radioButtonListItem = managementStatusList.Items.FindByValue(hrDepartmentManagementTypeID);
                if (radioButtonListItem != null)
                {
                    radioButtonListItem.Selected = true;
                }
                else
                {
                    // we should never reach this unless something changes
                    managementStatusList.SelectedIndex = UnmanagedHRDeptMgmtStatusTypeIndex;
                }
            }
        }

        /// <summary>
        /// Handles the datagrid sort event.
        /// </summary>
        /// <param name="source">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnSort(object source, DataGridSortCommandEventArgs e)
        {
            if (e.SortExpression == "HRDepartmentCode")
            {
                DataView dvHRDepts = HRDepartments.GetDataContainer().Tables[HRDepartmentsTableIndex].DefaultView;
                dvHRDepts.Sort = string.Format("{0} {1}", "HRDepartmentCode ", SortAscending ? "ASC" : "DESC");
                SortAscending = !SortAscending;
                dataGrid.DataSource = dvHRDepts;
                dataGrid.DataBind();
            }
        }

        /// <summary>
        /// Persist the changes to the HR Department's Management status. It also updates the datatable 
        /// in cache so that the database is in sync with the data in the dataset in memory. Updates are persisted
        /// to the database only when there is a change in management status. It should also be noted
        /// that HRDepartments with no management status (null HRDepartmentManagementTypeID column value) 
        /// information are considered "UnManaged". 
        /// </summary>
        /// <param name="sender">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnSave(object sender, EventArgs e)
        {
            DataTable hrDepartmentTable = HRDepartments.GetDataContainer().Tables[HRDepartmentsTableIndex];
            foreach (DataGridItem deptItem in dataGrid.Items)
            {
                int updatedMgmtTypeID = Convert.ToInt32(((RadioButtonList) deptItem.FindControl("managementStatusList")).SelectedValue);
                int hrDepartmentID = Convert.ToInt32(deptItem.Cells[0].Text);
                DataRow tableRow = hrDepartmentTable.Select(string.Format("{0} {1}", "HRDepartmentID = ", hrDepartmentID))[0];

                if ((tableRow != null && tableRow["HRDepartmentManagementTypeID"] != DBNull.Value && Convert.ToInt32(tableRow["HRDepartmentManagementTypeID"]) != updatedMgmtTypeID) ||
                    (tableRow != null && tableRow["HRDepartmentManagementTypeID"] == DBNull.Value && updatedMgmtTypeID != UnmanagedHRDeptMgmtStatusTypeID))
                {
                    HRDepartment.Save(DataAccess.GetConnectionString(), hrDepartmentID, updatedMgmtTypeID);

                    // update the table data
                    tableRow["HRDepartmentManagementTypeID"] = updatedMgmtTypeID;
                }
            }
            HRDepartments.Cache();
        }

        /// <summary>
        /// Handles datagrid click event. It caches the HRdepartmentID associated 
        /// with the datagrid row clicked and redirects to the profile page.
        /// </summary>
        /// <param name="source">The object raising an event.</param>
        /// <param name="e">Information accompanying the event itself.</param>
        protected void OnItemCommand(object source, DataGridCommandEventArgs e)
        {
            if (e.CommandName == "HRDepartmentCode")
            {
                Hashtable incomingData = (Hashtable) Session[Keys.IncomingDataKey] ?? new Hashtable();
                incomingData[Keys.HRDepartmentIdKey] = e.Item.Cells[0].Text;
                Session[Keys.IncomingDataKey] = incomingData;
                Response.Redirect("AdminHRDepartmentProfile.aspx");
            }
        }

        /// <summary>
        /// Ensures that at least one of the search criteria values has been provided. 
        /// </summary>
        /// <param name="source">The object raising an event.</param>
        /// <param name="args">Information accompanying the event itself.</param>
        protected void OnValidate(object source, ServerValidateEventArgs args)
        {
            args.IsValid = !(hrDepartmentCode.Text.Trim() == string.Empty && userName.Text.Trim() == string.Empty &&
                firstName.Text.Trim() == string.Empty && lastName.Text.Trim() == string.Empty);
        }

        /// <summary>
        /// Resets the subnavigation selected link(s) before the 
        /// header performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnHeaderNavigate(object sender, CommandEventArgs e)
        {
            adminSubNavigation.Reset();
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Wires up page events.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            base.OnInit(e);

            cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
        }

        #endregion
    }
}